<template>
  <div class="hc-table" ref="hcTableRef">
    <!-- 操作栏，在传入了buttons和查询条件等情况下 -->
    <div name="operation" v-if="props.showTableheader" class="operation" ref="thisTableHeaderRef">
      <!-- 操作按钮列表，目前基本以传入的插槽内容为主 -->
      <div class="btns-warpper">
        <slot name="btns">
          <el-button type="primary" @click="$emit('querySubmit')">示例按钮</el-button>
        </slot>
      </div>

      <slot name="query">
        <div class="query-warpper">
          <el-form :inline="true" :model="queryInfo" class="form-outter-show">
            <el-form-item :label="item.label" v-for="item in outterShowSearchList" :key="item.prop">
              <el-input v-if="item.type === 'input' || !item.type" v-model="queryInfo[item.prop]" :placeholder="item.placeholder" clearable />
              <el-select v-else-if="item.type === 'select'" v-model="queryInfo[item.prop]" :placeholder="item.placeholder" clearable>
                <el-option v-for="op in item.options" :key="op.value" :label="op.label" :value="op.value"></el-option>
              </el-select>
              <el-date-picker
                v-else-if="item.type.includes('date')"
                :type="item.type || 'date'"
                v-model="queryInfo[item.prop]"
                :placeholder="item.placeholder"
                :start-placeholder="item.startPlaceholder"
                :end-placeholder="item.endPlaceholder"
                clearable
              />
            </el-form-item>
          </el-form>

          <div class="query-handle">
            <HcButton type="silver" :icon="btnIconSearch" :activeIcon="btnIconSearchHover" @click="$emit('querySubmit')" title="查询" />
            <HcButton
              type="black"
              :icon="btnIconSearchFold"
              :activeIcon="btnIconSearchFold"
              title="展开"
              @click="isFoldSearchShow = !isFoldSearchShow"
            />
          </div>

          <div :class="['fold-search-warpper', { 'fold-search-warpper-show': isFoldSearchShow }]">
            <span class="close" @click="isFoldSearchShow = !isFoldSearchShow">x</span>
            <el-form :inline="true" :model="queryInfo" class="form-fold-search">
              <el-row :gutter="35">
                <el-col :span="8" class="query-col" v-for="item in foldSearchList" :key="item.prop">
                  <el-form-item :label="item.label">
                    <el-input v-if="item.type === 'input' || !item.type" v-model="queryInfo[item.prop]" :placeholder="item.placeholder" clearable />
                    <el-select v-else-if="item.type === 'select'" v-model="queryInfo[item.prop]" :placeholder="item.placeholder" clearable>
                      <el-option v-for="op in item.options" :key="op.value" :label="op.label" :value="op.value"></el-option>
                    </el-select>
                    <el-date-picker
                      v-else-if="item.type.includes('date')"
                      :type="item.type || 'date'"
                      v-model="queryInfo[item.prop]"
                      :placeholder="item.placeholder"
                      :start-placeholder="item.startPlaceholder"
                      :end-placeholder="item.endPlaceholder"
                      clearable
                    />
                  </el-form-item>
                </el-col>
              </el-row>
            </el-form>
            <div class="query-fold-handle">
              <el-button @click="$emit('querySubmit')">搜索</el-button>
              <el-button @click="resetForm">重置</el-button>
            </div>
          </div>
        </div>
      </slot>
    </div>

    <!-- table主体，负责数据展示 -->
    <el-table v-bind="$attrs" class="hc-table-ins" :height="tableHeight">
      <slot></slot>
    </el-table>

    <!-- 分页部分 -->
    <div class="hc-table-pagination" ref="thisPageSlotRef">
      <slot name="pagination" v-if="props.showPagination">
        <el-pagination
          background
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
          :total="props.dataTotal"
          :page-size="currentPageSize"
          :page-sizes="[suitablePagination, 20, 30, 50, 100]"
          layout="total,sizes,prev, pager, next ,jumper>"
        />
      </slot>
    </div>
  </div>
</template>

<script lang="ts" setup>
import btnIconSearch from "/@/assets/img/search.png";
import btnIconSearchHover from "/@/assets/img/search-hover.png";
import btnIconSearchFold from "/@/assets/img/search-fold.png";
import HcButton from "/@/components/hc-button/index.vue";

const DEFAULT_TABLE_HEIGHT = 200;
const DEFAULT_TABLE_ROW_NUMBER = 10;

const thisPageSlotRef = ref();

defineOptions({
  name: "hc-table",
  inheritAttrs: false,
});

const props = withDefaults(
  defineProps<{
    showPagination?: boolean; //是否展示分页部分
    showTableheader?: boolean; //是否展示表头部分
    searchList?: any[]; //搜索表单项生成配置
    dataTotal: number; //数据总条数
    rowHeight?: number; //行高
    padding?: number; //表格内边距
  }>(),
  {
    operations: () => [],
    showTableheader: true,
    showPagination: true,
    searchList: () => [],
    dataTotal: 0,
    rowHeight: 40,
    padding: 0,
  }
);

const queryInfo = defineModel<{
  [key: string]: any;
}>("queryInfo", { default: {} });

const emit = defineEmits(["querySubmit", "pageChange", "tableInit"]);

const hcTableRef = ref();
const thisTableHeaderRef = ref();
const tableHeight = ref(DEFAULT_TABLE_HEIGHT);
const suitablePagination = ref(DEFAULT_TABLE_ROW_NUMBER);
const currentPageSize = ref(DEFAULT_TABLE_ROW_NUMBER);
const isFoldSearchShow = ref(false);

const outterShowSearchList = props.searchList.filter((s) => s.outerShow);
const foldSearchList = props.searchList;

const tablePadding = computed(() => {
  return props.padding + "px";
});

const handleSizeChange = (size: number) => {
  queryInfo.value.pageSize = size;
  emit("pageChange");
};
const handleCurrentChange = (page: number) => {
  queryInfo.value.page = page;
  emit("pageChange");
};

const _getElementComputedStyle = (element: HTMLElement, prop: string) => {
  const style = window.getComputedStyle(element);
  return parseFloat(style.getPropertyValue(prop)) || 0;
};

const _getTableSuitableHeight = () => {
  const paddingTop = _getElementComputedStyle(hcTableRef.value.parentElement, "padding-top");
  const paddingBottom = _getElementComputedStyle(hcTableRef.value.parentElement, "padding-bottom");
  return Math.max(
    DEFAULT_TABLE_HEIGHT,
    hcTableRef.value.parentElement?.clientHeight - //表格父组件的高度
      paddingTop - //表格父组件的padding-top
      paddingBottom - //表格父组件的padding-bottom
      (props.showPagination ? thisPageSlotRef.value.clientHeight : 0) - //分页高度
      (props.showTableheader ? thisTableHeaderRef.value.clientHeight : 0) -
      props.padding * 2 //内边距
  );
};

const settingTableSuitableData = () => {
  tableHeight.value = _getTableSuitableHeight();
  queryInfo.value.pageSize = currentPageSize.value = suitablePagination.value = Math.floor(tableHeight.value / props.rowHeight);
  emit("tableInit");
};

const resetForm = () => {
  const toRetainProps = ["page", "pageSize"];
  for (const key in queryInfo.value) {
    if (!toRetainProps.includes(key)) {
      delete queryInfo.value[key];
    }
  }
  emit("querySubmit");
};

onMounted(() => {
  nextTick(() => {
    settingTableSuitableData();
  });
});

onActivated(() => {
  nextTick(() => {
    settingTableSuitableData();
  });
});

defineExpose({
  suitablePagination: suitablePagination.value, //先导出，未使用
});
</script>

<style lang="scss" scoped>
.hc-table {
  height: 100%;
  box-sizing: border-box;
  padding: v-bind(tablePadding);
  .operation {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding-bottom: 10px;
    .btns-warpper {
      display: flex;
    }

    .query-warpper {
      :deep(.el-form-item--default) {
        margin-bottom: 0;
      }

      .query-handle {
        display: flex;
        align-items: center;
      }
      display: flex;
      .fold-search-warpper {
        position: absolute;
        left: 0;
        top: 0;
        width: 0px;
        height: 0px;
        background-color: #2d363b;
        border-radius: 1.428571rem /* 20/14 */;
        box-shadow: 0.142857rem /* 2/14 */ 0.142857rem /* 2/14 */ 0.5rem /* 7/14 */ #1f1f1f;
        overflow: hidden;
        z-index: 1000;
        box-sizing: border-box;

        .query-fold-handle {
          margin-top: 1.428571rem /* 20/14 */;
          display: flex;
          justify-content: center;
        }

        .close {
          position: absolute;
          right: 0.714286rem /* 10/14 */;
          top: 0.714286rem /* 10/14 */;
          height: 0.714286rem /* 10/14 */;
          width: 0.714286rem /* 10/14 */;
          padding: 0.285714rem /* 4/14 */;
          display: flex;
          align-items: center;
          justify-content: center;
          border: 1px solid white;
          border-radius: 50%;
          color: white;
          cursor: pointer;
        }

        .query-col {
          text-align: left;
          margin-bottom: 1.428571rem /* 20/14 */;
        }
      }
      .fold-search-warpper-show {
        padding: 2.857143rem /* 40/14 */ 0.714286rem /* 10/14 */;
        width: 100%;
        height: auto;
        min-height: 200px;
      }
    }
  }
  .hc-table-ins {
  }

  .hc-table-pagination {
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 10px 0;
  }
}
</style>
